package com.googlecode.compliancechecker;

import java.io.IOException;
import java.io.InputStream;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

/**
 * Utility class to verify that a class provides an implementation for a
 * reference.
 * 
 * @author Marc-Christian Schulze
 * 
 */
public class MethodReferenceVerifier {

	private ClassVisitor	cv;
	private ClassReader		cr;
	private boolean			success;
	private MethodReference	ref;

	public MethodReferenceVerifier(InputStream stream) throws IOException {
		cv = new MyVisitor();
		cr = new ClassReader(stream);
	}

	public boolean verify(MethodReference ref) {
		this.ref = ref;
		cr.accept(cv, 0);

		return success;
	}

	private class MyVisitor implements ClassVisitor {

		private String	className;

		public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
			className = name;
		}

		public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
			if (ref.getTypeName().equals(className) && ref.getMethodName().equals(name)
					&& ref.getSignature().equals(desc)) {
				success = true;
			}
			return null;
		}

		public void visitSource(String source, String debug) {
		}

		public void visitOuterClass(String owner, String name, String desc) {
		}

		public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
			return null;
		}

		public void visitAttribute(Attribute attr) {
		}

		public void visitInnerClass(String name, String outerName, String innerName, int access) {
		}

		public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
			return null;
		}

		public void visitEnd() {
		}
	}
}
